package cn.iocoder.yudao.module.brokerage.merchant.dao;

import cn.iocoder.yudao.framework.business.basic.dao.mapper.CoreMapper;
import cn.iocoder.yudao.framework.business.basic.dao.query.CoreLambdaQueryWrapper;
import cn.iocoder.yudao.framework.common.exception.Assertions;
import cn.iocoder.yudao.module.api.brokerage.agency.vo.AgencyBrokerageMoneyTrendVO;
import cn.iocoder.yudao.module.brokerage.merchant.pojo.po.AgencyMerchantDO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 推广商家 Mapper
 *
 * @author 山野羡民
 */
@Mapper
public interface BrokerageMerchantMapper extends CoreMapper<AgencyMerchantDO> {

    default AgencyMerchantDO findOrCreateByShopId(Long shopId) {
        CoreLambdaQueryWrapper<AgencyMerchantDO> wrapper = new CoreLambdaQueryWrapper<>();
        wrapper.eq(AgencyMerchantDO::getShopId, shopId);
        wrapper.limitN(1);
        AgencyMerchantDO entity = selectOne(wrapper);
        if (entity == null) {
            entity = new AgencyMerchantDO();
            entity.setShopId(shopId);
            entity.setAgencyUserId(0L);
            entity.setTotalOrderCount(0);
            entity.setTotalOrderPrice(0);
            insert(entity);
        }
        return entity;
    }

    default int increaseSettlementMoney(Long shopId, Integer basePrice, Integer settlementMoney) {
        Assertions.isTrue(settlementMoney >= 0, "增加的结算金额必须大于等于0");
        if (settlementMoney == 0) {
            return 0;
        }
        LambdaUpdateWrapper<AgencyMerchantDO> wrapper = new LambdaUpdateWrapper<AgencyMerchantDO>()
                .setSql(" total_order_count = total_order_count + 1"
                        + ", total_order_price = total_order_price + " + basePrice
                        + ", total_settlement_money = total_settlement_money + " + settlementMoney)
                .eq(AgencyMerchantDO::getShopId, shopId);
        return update(null, wrapper);
    }

    default int decreaseSettlementMoney(Long shopId, Integer basePrice, Integer settlementMoney) {
        // 注意：理论上佣金可能已经提现，这时会扣出负数，确保平台不会造成损失
        Assertions.isTrue(settlementMoney >= 0, "减少的结算金额必须大于等于0");
        if (settlementMoney == 0) {
            return 0;
        }
        LambdaUpdateWrapper<AgencyMerchantDO> wrapper = new LambdaUpdateWrapper<AgencyMerchantDO>()
                .setSql(" total_order_count = total_order_count - 1"
                        + ", total_order_price = total_order_price - " + basePrice
                        + ", total_settlement_money = total_settlement_money - " + settlementMoney)
                .eq(AgencyMerchantDO::getShopId, shopId);
        return update(null, wrapper);
    }

    @Select("""
            SELECT COUNT(shop_id)
            FROM brokerage_merchant
            WHERE agency_user_id = #{agencyUserId} AND deleted = FALSE
            """)
    Integer selectInviteMerchantCount(@Param("agencyUserId") Long agencyUserId);

    @Select("""
            SELECT SUM(bonus_money)
            FROM brokerage_merchant_record
            WHERE user_id = #{agencyUserId} AND status = 0 AND deleted = FALSE
            """)
    Integer selectFreezingBonusMoney(@Param("agencyUserId") Long agencyUserId);

    @Select("""
            SELECT SUM(bonus_money)
            FROM brokerage_merchant_record
            WHERE user_id = #{agencyUserId} AND unfreeze_time >= CURDATE() AND unfreeze_time < CURRENT_DATE() + INTERVAL 1 DAY AND status = 1 AND deleted = FALSE
            """)
    Integer selectTodayUnfreezeBonusMoney(@Param("agencyUserId") Long agencyUserId);

    @Select("""
            SELECT SUM(bonus_money)
            FROM brokerage_merchant_record
            WHERE user_id = #{agencyUserId} AND status = 1 AND deleted = FALSE
            """)
    Integer selectTotalUnfreezeBonusMoney(@Param("agencyUserId") Long agencyUserId);

    @Select("""
            SELECT DATE_FORMAT(create_time, '%Y-%m-%d') AS date, SUM(bonus_money) AS money
            FROM brokerage_merchant_record
            WHERE unfreeze_time BETWEEN #{beginTime} AND #{endTime} AND user_id = #{agencyUserId} AND deleted = FALSE
            GROUP BY date
            """)
    List<AgencyBrokerageMoneyTrendVO> selectListByAgencyUserIdAndUnfreezeTime(@Param("agencyUserId") Long agencyUserId, @Param("beginTime") LocalDateTime beginTime, @Param("endTime") LocalDateTime endTime);
}